# import urllib
from urllib import request
from urllib import parse
import time
import json
import configparser
from Config import ConfigController
from Logger import Logger
from Email import Email


# 发送模版消息的类，不过会有文件资源占用的问题
class WechatApi:
    def __init__(self):
        # self.emailController = Email.EmailController()
        self.__configPath = "../Config/config.ini"
        self.__loggerConfigPath = '../Logger/logging.json'
        self.config = ConfigController.ConfigController(self.__configPath)
        self.__appID = self.config.getConfig(sectionName="WECHAT",
                                             optionName="APP_ID")
        self.__appSecret = self.config.getConfig(sectionName="WECHAT",
                                                 optionName="APP_SECRET")
        self.__accessTokenUrl = self.config.getConfig(sectionName="WECHAT",
                                                      optionName='ACCESS_TOKEN_URL')
        self.__grantType = self.config.getConfig(sectionName="WECHAT",
                                                 optionName="GRANT_TYPE")
        self.__accessToken = ''
        self.__lastRequire = time.time()
        self.__urlData = parse.urlencode({
            "grant_type":self.__grantType,
            "appid": self.__appID,
            "secret" : self.__appSecret
        })
        self.logger = Logger.Logger(self.__loggerConfigPath)

    # 获取接口调用凭证，刷新token和有效期
    def getAccessToken(self):
        accessToken = self.config.getConfig(sectionName='WECHAT',
                                            optionName='ACCESS_TOKEN')
        validTime = float ( self.config.getConfig(sectionName='WECHAT',
                                                  optionName='TOKEN_VALID_TIME'))
        lastRequired = float ( self.config.getConfig(sectionName='WECHAT',
                                                     optionName='TOKEN_LAST_REQUIRED'))
        # 两次调用获取token的间隔如果超过了token的有效期，刷新token
        if self.isAccessTokenOutOfDate(validTime,lastRequired):
            url = self.__accessTokenUrl+self.__urlData
            httpRequest = request.Request(url)
            httpResponse = request.urlopen(httpRequest)
            returnSource = httpResponse.read().decode('utf-8')
            returnJson = json.loads(returnSource)

            #如果调用微信API接口出现了问题
            if returnJson.get('errcode', False):
                self.logger.fileInfoLogger.error(returnJson.get('errmsg', ""))
                return False

            #如果成功返回access_token，刷新配置文件
            else:
                accessToken = returnJson['access_token']
                self.config.setConfig(sectionName='WECHAT',
                                      optionName='ACCESS_TOKEN',
                                      value = accessToken)
                self.config.setConfig(sectionName='WECHAT',
                                      optionName='TOKEN_VALID_TIME',
                                      value=str(returnJson['expires_in']))
                self.config.setConfig(sectionName='WECHAT',
                                      optionName='TOKEN_LAST_REQUIRED',
                                      value=str(time.time()))
                #保存配置文件
                if self.config.saveConfig(self.__configPath):
                    self.logger.fileInfoLogger.info('Required access token %s, valid in %s s' % (accessToken, str(returnJson['expires_in'])))
                else:
                    self.logger.fileInfoLogger.error('Save config file failed. Maybe file system error.')
                    emailController = Email.EmailController()
                    emailController.sendEmail(msgStr="获取接口调用凭证时出错，保存配置文件失败！位于Api.py line74 ",subject="保存配置文件失败！",withLog=False)
                    return None

        # 两次调用没有超过token的有效期，不刷新 / 刷新完毕，返回刷新后的token
        return accessToken

    # 获取所有模版列表
    def getAllTemplate(self):
        token = self.__accessToken
        url = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=%s" % (token)
        httpRequest = request.Request(url)
        httpResponse = request.urlopen(httpRequest)
        responseSource = httpResponse.read().decode('utf-8')
        responseJson = json.loads(responseSource)
        if responseJson.get('errcode', False):
            self.logger.fileInfoLogger.error("Time: %f, with error: %s" %(time.time(),responseJson.get('errmsg', "")))
            return False
        else:
            templist = responseJson['template_list']
            return templist

    def sendTemplateMessage(self, openID, templateID, data, url):
        userID = data['keyword1']['value']
        postData = json.dumps({
            'touser': openID,
            'template_id': templateID,
            'url': url,
            'data': data
        }).encode("utf-8")
        url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s" % (self.getAccessToken())
        httpRequest = request.Request(url)
        httpResponse = request.urlopen(httpRequest, data=postData)
        responseSource = httpResponse.read().decode('utf-8')
        responseJson = json.loads(responseSource)
        print(responseSource)
        if (responseJson['errcode'] == 0):
            self.logger.fileInfoLogger.info("Time : %f, successfully send message to %s" %(time.time(),userID))
            return responseJson
        else:
            self.logger.fileInfoLogger.error("Time: %f, failed to send message, reason: %s" %(time.time(),responseJson['errmsg']))
            emailController = Email.EmailController()
            emailController.sendEmail(msgStr="发送模版消息失败，原因是 %s ，位于Api.py line 114" %(responseJson['errmsg']),subject="发送模版消息失败",withLog=False)
            return None

    # 检查token是否超过有效期-辅助函数，不需直接调用
    def isAccessTokenOutOfDate(self,validTime=-1.0,lastRequired=0.0):
        timeGap = time.time() - lastRequired
        return validTime <= timeGap


if __name__ == "__main__":
    api = WechatApi()
    url = "http://weixin.qq.com/download"

    openid = api.config.getConfig(sectionName='WECHAT',
                                  optionName='OPENID_YL')
    templateID = api.config.getConfig(sectionName='WECHAT',
                                      optionName='TEMPLATE_ID')
    data = {
        "first": {
            "value": "你好，你有一条新的上线消息，敬请查收",
            "color": "#173177"
        },
        "keyword1": {
            "value": "test_userid",
            "color": "#173177"
        },
        "keyword2": {
            "value": "test_username",
            "color": "#173177"
        },
        "keyword3": {
            "value": "有线登陆",
            "color": "#173177"
        },
        "keyword4": {
            "value": "北洋园校区",
            "color": "#173177"
        },
        "keyword5": {
            "value": "2.5GB",
            "color": "#173177"
        },
        "remark": {
            "value": "如非本人登录，请尽快处理。",
            "color": "#173177"
        }
    }
    print(api.sendTemplateMessage(openID=openid,
                                  templateID=templateID,
                                  data=data,
                                  url=url))
    # print(api.getAllTemplate())
